
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>
#include <string.h>


typedef void (*we_proc)();
typedef int (*dump)();

we_proc gen(char *s, int n);
dump gendump();

void *malloc_exec(size_t sz);

int my_syscall(void) {
    asm (
            "movl %0, %%ecx\n\t"
            "movl $4, %%eax\n\t"
            "movl $1, %%ebx\n\t"
            "movl $8, %%edx\n\t"
            "int $0x80\n"
            :
            : "r" ("goodbye\n")
            //: /* no clobbered list */
        );
    
    return 0;
}

// int main(int agrc, char **argv) {
// 
//     write(1, "hello\n", 6);
//     //write(1, "goodbye\n", 8);
//     
//     // wont work when compiled in 32 bit mode because
//     // NR_write in 32 bit is 4
//     // syscall(1, 1, "goodbye\n", 8);
// 
//     // syscall(4, 1, "goodbye\n", 8);
// 
//     my_syscall();
// 
//     exit(0);
// }

// int main(int argc, char **argv) {
//     we_proc a, b;
//     a = gen("hello\n", 3);
//     b = gen("goodbye\n", 4);
//     a();
//     write(1, "oops\n", 5);
//     return 0;
// }

int main(int argc, char **argv) {

    dump d;
    d = gendump();
    int num = (*d)();
    printf("number = %d \n", num);

    return 0;
}


 we_proc gen(char *s, int n) {

     char a[] = {
         0xB8, 0x01, 0x00, 0x00, 0x00,
         0xC3            
     };
     int size = sizeof(a);

     we_proc funcPt = malloc_exec(size);

     memcpy(funcPt, a, size);
    
     return funcPt;   
 }

dump gendump() {

     char a[] = {
         0xB8, 0x01, 0x00, 0x00, 0x00,
         0xC3            
     };

     int size = sizeof(a);

     dump funcPt = malloc_exec(size);

     memcpy(funcPt, a, size);
    
     return funcPt;   
 }


void *malloc_exec(size_t sz) {
    long pagesize = sysconf(_SC_PAGE_SIZE);
    void *p;
    if (posix_memalign(&p, pagesize, sz) != 0) {
      printf ("oops: memalign failed!\n");
      exit (-1);
    }
    if (mprotect(p, sz, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
      printf ("oops: mprotect failed!\n");
      exit (-1);
    }
    return p;
}

